import { DeviceEventEmitter } from "react-native";
import { XStorage } from 'react-native-easy-app';
import { RNStorage } from "../common/Storage/AppStorage";
import XLog from "../libs/XLog";
import { HoleType, ProductID, RegisterType, ValidType, DeviceModelID, onlineStatus, LightMode, Default_Retry_Count, InterfaceType, MeterConfig, SerialConfig, DevicePort } from "./LogicConstant";
import { generateLoopMap, generateInitDefaultLoops, generateGateInitValue } from "./TestDataGenerate";
import { Default_Request_List, RS_Device_Type } from "../libs/SerialCommon";
export default class DataCenter {
    static Cache_Enable = true;
    static machineIp = "";//本机ip
    static serverIp = "";//服务器ip
    static machineCode = "";//本机机器码
    
    static serverId = "";//服务器id
    static gateId = "local"; //本网关ID
    //static gateName = "";//本网关名字
    static gateSecret = "";//网关通信秘钥
    //static portalNumber = "";//本地网关桩号
    static tunnelType = 0;//隧道类型
    static tunnelId = 0; //隧道id
    static tunnelName = "";//隧道名字

    static masterIp = "";//主控ip
    static masterId = "";//主控机器码
    static masterSecret = "";//主控的secret
    
    static isMaster = false;//本机是否是主控
    static registerStatus = RegisterType.UN_REGISTER;//本机注册状态
    static registerError = "";//注册失败的原因

    static colonyGatesMap = {};//集群服务器信息
    static colonyGatesValue = {};//集群服务器真实数据
    static tunnelGatesMap = {};//单洞网关信息
    static gateSegmentMap = {};
    static strategyListMap = {};//策略配置列表

    static colonyOriginData = [];
    static tunnelOriginData = [];
    static strategyListOriginData = [];

    static serverKey = "";

    static meterConfigList = Default_Request_List;      // 电表配置列表
    static smartMeterData = {"realtime": {}, "stat": {}};

    static loopControllerList = [];
    // static loopControllerList = [
    //     {id: 1, index: 1, key: "1", type: RS_Device_Type.LOOP_4WAY, 
    //     address: "888899999999", option: {...SerialConfig, port: 2}, interface: InterfaceType.USB_SERIAL},
    //     {id: 2, index: 2, key: "1", type: RS_Device_Type.LOOP_4WAY, 
    //     address: "888888888666", option: {...SerialConfig, port: 2}, interface: InterfaceType.USB_SERIAL},
    //     // {id: 1, index: 1, key: "2", type: RS_Device_Type.LOOP_6WAY, 
    //     // address: "00D8", option: {...SerialConfig, port: 1}, interface: InterfaceType.USB_SERIAL},
    //     // {id: 2, index: 2, key: "2", type: RS_Device_Type.LOOP_6WAY, 
    //     // address: "00D8", option: {...SerialConfig, port: 1}, interface: InterfaceType.USB_SERIAL},
    // ];
    // static smartMeterList = [];
    static smartMeterList = [
        {id: 1, index: 1, key: "3", type: RS_Device_Type.METER, 
        address: "34", option: {...MeterConfig, port: 0}, interface: InterfaceType.USB_SERIAL},
        // {id: 2, index: 2, key: "3", type: RS_Device_Type.METER, 
        // address: "34", option: {...MeterConfig, port: 2}, interface: InterfaceType.USB_SERIAL}
    ];

    static initDataCenter() {
        let defaultLoops = generateInitDefaultLoops();
        this.colonyGatesMap[this.gateId] = {
            gateName: "",
            gateId: this.gateId,
            onlineStatus: onlineStatus.ONLINE,
            portalNumber: "",
            loop: generateLoopMap(defaultLoops),
        };
        this.colonyGatesValue[this.gateId] = generateGateInitValue(onlineStatus.ONLINE, defaultLoops);
    }

    static async doRegister(serverIp, code) {
        this.serverIp = serverIp;
        this.machineCode = code;
    
        this.serverId = "";//服务器id
        this.gateId = "local"; //本网关ID
        this.gateSecret = "";//网关通信秘钥

        this.tunnelType = 0;//隧道类型
        this.tunnelId = 0; //隧道id
        this.tunnelName = "";//隧道名字

        this.masterIp = "";//主控ip
        this.masterId = "";//主控机器码
        this.masterSecret = "";//主控的secret
    
        this.isMaster = false;//本机是否是主控
        this.registerStatus = RegisterType.UN_REGISTER;//本机注册状态
        this.registerError = "";//注册失败的原因

        this.colonyGatesMap = {};//集群服务器信息
        this.colonyGatesValue = {};//集群服务器真实数据
        this.tunnelGatesMap = {};//单洞网关信息
        this.gateSegmentMap = {};
        this.strategyListMap = {};//策略配置列表

        this.colonyOriginData = [];
        this.tunnelOriginData = [];
        this.strategyListOriginData = [];

        await XStorage.clear();

        this.initDataCenter();
    }

    static doRegisterSuccess(data) {
        this.registerStatus = RegisterType.REGISTER_SUCCESS;
        this.serverId = data.serverId;
        this.gateId = data.gateId;
        this.tunnelType = data.tunnelType;
        this.tunnelId = data.tunnelId;
        this.tunnelName = data.tunnelName;
        this.serverKey = data.serverKey;
        for(let item of data.group||[]) {
            if(item.gateId == this.gateId) {//本柜
                this.gateSecret = item.gateSecret;
                this.colonyGatesMap[this.gateId] = {
                    gateName: item.gateName,
                    gateId: this.gateId,
                    onlineStatus: onlineStatus.ONLINE,
                    portalNumber: item.portalNumber,
                    loop: generateLoopMap(item.loop)
                };
                this.colonyGatesValue[this.gateId] = generateGateInitValue(onlineStatus.ONLINE, item.loop);
                if(this.colonyGatesValue["local"]) {
                    delete this.colonyGatesValue["local"];
                }
                this.initLoopControllerList(item.loopController);
                this.initSmartMeterList(item.smartMeter);
                this.setMeterConfigList(item.smartMeterConf);
                this.updateDeviceList();
            }
            if(item.isMaster) {
                this.masterIp = item.gateIp;
                this.masterId = item.gateId;
                this.masterSecret = item.gateSecret;
                if(item.gateId == this.gateId) {
                    this.isMaster = true;
                } else {
                    this.isMaster = false;
                }
            }
        }

        if(this.Cache_Enable) {
            RNStorage.registerInfo = {
                registerStatus: this.registerStatus,
                machineCode: this.machineCode,
            }
            RNStorage.registerRsp = {
                gateId: this.gateId,
                gateSecret: this.gateSecret,
                tunnelType: this.tunnelType,
                tunnelId: this.tunnelId,
                tunnelName: this.tunnelName,
            };
            RNStorage.serverInfo = {
                serverIp: this.serverIp,
                serverId: this.serverId,
                serverKey: this.serverKey,
            };
            RNStorage.masterInfo = {
                masterIp: this.masterIp,
                masterId: this.masterId,
                isMaster: this.isMaster,
                masterSecret: this.masterSecret,
            };
            RNStorage.colonyGatesValue = this.colonyGatesValue;
        }
        DeviceEventEmitter.emit("localCabinet");
        DeviceEventEmitter.emit("register");
    }

    static doRegisterFail(ret, reason) {
        this.registerStatus = ret;
        this.registerError = reason;
        if(this.Cache_Enable) {
            RNStorage.registerInfo = {
                registerStatus: ret,
                registerError: reason,
                machineCode: this.machineCode,
            };
        }
        DeviceEventEmitter.emit("register");
    }

    static reloadBaseFromCache() {
        if(!this.Cache_Enable) {
            return;
        }
        if(RNStorage.serverInfo) {
            this.serverIp = RNStorage.serverInfo.serverIp;
            this.serverId = RNStorage.serverInfo.serverId;
            this.serverKey = RNStorage.serverInfo.serverKey;
        }
        if(RNStorage.masterInfo) {
            this.masterIp = RNStorage.masterInfo.masterIp;
            this.masterId = RNStorage.masterInfo.masterId;
            this.isMaster = RNStorage.masterInfo.isMaster;
            this.masterSecret = RNStorage.masterInfo.masterSecret;
        }
        if(RNStorage.registerInfo) {
            this.machineCode = RNStorage.registerInfo.machineCode;
            this.registerStatus = RNStorage.registerInfo.registerStatus;
            this.registerError = RNStorage.registerInfo.registerError;
        }
        if(RNStorage.registerRsp) {
            this.gateId = RNStorage.registerRsp.gateId;
            this.gateSecret = RNStorage.registerRsp.gateSecret;
            this.tunnelType = RNStorage.registerRsp.tunnelType;
            this.tunnelId = RNStorage.registerRsp.tunnelId;
            this.tunnelName = RNStorage.registerRsp.tunnelName;
        }
        console.log("RNStorage.serverInfo:",RNStorage.serverInfo);
        console.log("RNStorage.masterInfo:",RNStorage.masterInfo);
        console.log("RNStorage.registerInfo:",RNStorage.registerInfo);
        console.log("RNStorage.registerRsp:",RNStorage.registerRsp);
    }

    static setColonyGates(data) {
        this.colonyOriginData = data;
        this.colonyGatesMap = {};
        for(let gate of (data||[])) {
            this.colonyGatesMap[gate.gateId] = Object.assign({}, gate);
            this.colonyGatesMap[gate.gateId].loop = generateLoopMap(gate.loop);
            if(!this.colonyGatesValue[gate.gateId]) {
                this.colonyGatesValue[gate.gateId] = generateGateInitValue(gate.onlineStatus, gate.loop);
            }
            // else {
            //     this.colonyGatesValue[gate.gateId].onlineStatus = gate.onlineStatus;
            // }
        }
        DeviceEventEmitter.emit("colonyCabinet");
        this.updateColonyGateCache();
        this.updateColonyGateValueCache();
        this.updateColonyOriginDataCache();
    }

    static updateColonyOriginDataCache() {
        if(this.Cache_Enable) {
            RNStorage.colonyOriginData = this.colonyOriginData;
        }
    }

    static updateColonyGateCache() {
        if(this.Cache_Enable) {
            RNStorage.colonyGatesMap = this.colonyGatesMap;
        }
    }

    static reloadColonyOriginDataFromCache() {
        if(this.Cache_Enable && RNStorage.colonyOriginData) {
            this.colonyOriginData = RNStorage.colonyOriginData;
        }
        console.log("reloadColonyOriginDataFromCache:", RNStorage.colonyOriginData);
    }

    static reloadColonyFromCache() {
        if(this.Cache_Enable && RNStorage.colonyGatesMap) {
            this.colonyGatesMap = RNStorage.colonyGatesMap;
        }
        console.log("reloadColonyFromCache:", RNStorage.colonyGatesMap);
    }

    static updateColonyGateValueCache() {
        if(this.Cache_Enable) {
            RNStorage.colonyGatesValue = this.colonyGatesValue;
        }
    }

    static reloadColonyGateLoopValueFromCache() {
        if(this.Cache_Enable && RNStorage.colonyGatesValue) {
            this.colonyGatesValue = RNStorage.colonyGatesValue;
        }
        console.log("reloadColonyGateLoopValueFromCache:", RNStorage.colonyGatesValue);
    }

    static setTunnelGates(data) {
        this.tunnelOriginData = data;
        this.tunnelGatesMap = {};
        this.tunnelGatesMap = {};
        for(let segment of (data||[])) {
            this.tunnelGatesMap[segment.sectionId] = Object.assign({}, segment);
            for(let groupItem of segment.group) {
                for(let loop of groupItem.loop||[]) {
                    let obj = this.gateSegmentMap[loop.gateId] || {};
                    obj[loop.loopNumber] = {...loop, sectionId: segment.sectionId, groupId: groupItem.groupId};
                    this.gateSegmentMap[loop.gateId] = obj;
                }
            }
        }
        DeviceEventEmitter.emit("tunnelCabinet");
        this.updateTunnelGateCache();
        this.updateTunnelOriginDataCache();
    }

    static updateTunnelOriginDataCache() {
        if(this.Cache_Enable) {
            RNStorage.tunnelOriginData = this.tunnelOriginData;
        }
    }

    static updateTunnelGateCache() {
        if(this.Cache_Enable) {
            RNStorage.tunnelGatesMap = this.tunnelGatesMap;
            RNStorage.gateSegmentMap = this.gateSegmentMap;
        }
    }

    static reloadTunnleOriginDataFromCache() {
        if(this.Cache_Enable && RNStorage.tunnelOriginData) {
            this.tunnelOriginData = RNStorage.tunnelOriginData;
        }
        console.log("reloadTunnleOriginDataFromCache:", RNStorage.tunnelOriginData);
    }

    static reloadTunnelGatesFromCache() {
        if(this.Cache_Enable && RNStorage.tunnelGatesMap) {
            this.tunnelGatesMap = RNStorage.tunnelGatesMap;
        }
        if(this.Cache_Enable && RNStorage.gateSegmentMap) {
            this.gateSegmentMap = RNStorage.gateSegmentMap;
        }
        console.log("reloadTunnelGatesFromCache:", RNStorage.tunnelGatesMap, RNStorage.gateSegmentMap);
    }

    static setStrategyList(data) {
        this.strategyListOriginData = data;
        this.strategyListMap = {};
        for(let s of data||[]) {
            this.strategyListMap[s.id] = s;
        }
        DeviceEventEmitter.emit("strategyList");
        this.updateStrategyMapDataCache();
        this.updateStrategyOriginDataCache();
    }

    static updateStrategyMapDataCache() {
        if(this.Cache_Enable) {
            RNStorage.strategyListMap = this.strategyListMap;
        }
    }

    static updateStrategyOriginDataCache() {
        if(this.Cache_Enable) {
            RNStorage.strategyListOrginData = this.strategyListOriginData;
        }
    }

    static reloadStrategyFromCache() {
        if(this.Cache_Enable && RNStorage.strategyListMap) {
            this.strategyListMap = RNStorage.strategyListMap;
        }
        console.log("reloadStrategyFromCache:", RNStorage.strategyListMap);
    }

    static reloadStrategyOriginDataFromCache() {
        if(this.Cache_Enable && RNStorage.strategyListOrginData) {
            this.strategyListOriginData = RNStorage.strategyListOrginData;
        }
        console.log("reloadStrategyOriginDataFromCache:", RNStorage.strategyListOrginData);
    }

    static setMeterConfigList(data){
        if(data){
            this.meterConfigList = data;
        }
        this.updateMeterConfigList();
    }

    static updateMeterConfigList(){
        if(this.Cache_Enable){
            RNStorage.meterConfigList = this.meterConfigList;
        }
    }

    static reloadMeterConfigListFromCache(){
        if(this.Cache_Enable && RNStorage.meterConfigList) {
            this.meterConfigList = RNStorage.meterConfigList;
        }
        console.log("reloadMeterConfigListFromCache:", RNStorage.meterConfigList);
    }

    static updateDeviceList(){
        let deviceList = {
            "loop": this.loopControllerList,
            "meter": this.smartMeterList
        }
        if(this.Cache_Enable){
            RNStorage.deviceList = deviceList;
        }
    }

    static reloadDeviceListFromCache(){
        if(this.Cache_Enable && RNStorage.deviceList) {
            let deviceList = RNStorage.deviceList;
            this.loopControllerList = deviceList.loop;
            this.smartMeterList = deviceList.meter;
        }
        console.log("reloadDeviceListFromCache:", RNStorage.deviceList);
    }

    static reloadAllFromCache() {
        this.reloadBaseFromCache();
        this.reloadColonyFromCache();
        this.reloadColonyGateLoopValueFromCache();
        this.reloadTunnelGatesFromCache();
        this.reloadStrategyFromCache();
        this.reloadColonyOriginDataFromCache();
        this.reloadTunnleOriginDataFromCache();
        this.reloadStrategyOriginDataFromCache();
        this.reloadMeterConfigListFromCache();
        this.reloadDeviceListFromCache();
    }

    static getTunnleBaseInfo() {
        let holeType = HoleType.filter(item=>item.id == this.tunnelType);
        let holeTypeName = holeType && holeType.length > 0 ? holeType[0].name : "";
        return (this.tunnelName + holeTypeName) || "";
    }

    static getStrategyList() {
        return Object.values(this.strategyListMap);
    }

    static getLocalCabinetData() {
        let ret = Object.assign({}, this.colonyGatesMap[this.gateId]);
        ret.onlineStatus = this.colonyGatesValue[this.gateId]?.onlineStatus;
        ret.valid = this.colonyGatesValue[this.gateId]?.valid;
        ret.loop = Object.values(ret?.loop||{});
        for(let loopItem of ret.loop ||[]) {
            loopItem.loopCurrentValue = this.queryGateLoopCurrentValue(this.gateId, loopItem.loopNumber);
        }
        return ret;
    }

    static getLocalCabinetLoops() {
        return Object.values(this.colonyGatesMap[this.gateId]?.loop||{});
    }

    static updateLocalCabinetLoops(data){
        for(var item of data.message){
            let loop = this.colonyGatesValue[this.gateId]?.loop?.[item.lamp];
            if(loop) {
                loop.vol = item.vol;
                // loop.current = item.current;
                // loop.power = item.power;
                // loop.leak = item.leak;
                // // loop.loopCurrentValue = (this.lightMode.value == LightMode.POSITIVE_MODE.value) ? item.light : 100 - item.light;
                loop.loopCurrentValue = item.light;
                // loop.color = item.color;
                loop.lamp = item.lamp;
            }
        }
        if(this.colonyGatesValue[this.gateId]?.valid){
            this.colonyGatesValue[this.gateId].valid[data.index] = ValidType.VALID;
        }
        DeviceEventEmitter.emit("localCabinet");
        this.updateColonyGateValueCache();
    }

    static updateInvalidState(data){
        if(this.colonyGatesValue[this.gateId]?.valid){
            this.colonyGatesValue[this.gateId].valid[data.index] = ValidType.INVALID;
        }
        DeviceEventEmitter.emit("localCabinet");
        this.updateColonyGateValueCache();
    }

    static getTunnelGates() {
        return [...Object.values(this.tunnelGatesMap)];
    }

    static getColonyExceptLocalCabinetData() {
        let ret = [];
        for(let gate of Object.values(this.colonyGatesMap)) {
            if(gate.gateId == this.gateId || gate.gateId == "local") {
                continue;
            }
            let item = Object.assign({}, gate);
            //item.onlineStatus = this.colonyGatesValue[gate.gateId]?.onlineStatus || gate.onlineStatus;
            item.valid = this.colonyGatesValue[gate.gateId]?.valid;
            item.loop = Object.values(item.loop);
            for(let loopItem of item.loop ||[]) {
                loopItem.loopCurrentValue = this.colonyGatesValue[gate.gateId]?.loop[loopItem.loopNumber]?.loopCurrentValue;
            }
            ret.push(item);
        }
        return ret;
    }

    static getCabinetDeviceInfo(id, valid){
        let value = this.colonyGatesValue[this.gateId].loop;
        if(!value) {
            return null;
        }
        let property = {
            "productId": ProductID.LOOP,
            "identifierId": DeviceModelID.LOOP,
            "onlineStatus": this.colonyGatesValue[this.gateId].onlineStatus,
            //"id": id,
            // "loop1Brightness": "" + value[1].loopCurrentValue,
            // "loop2Brightness": "" + value[2].loopCurrentValue,
            // "loop3Brightness": "" + value[3].loopCurrentValue,
            // "loop4Brightness": "" + value[4].loopCurrentValue,
            // "valid": this.colonyGatesValue[this.gateId].valid
        };
        for (var val of Object.keys(value||{})){
            property["loop" + val + "Brightness"] = value[val].loopCurrentValue;
        }
        property.valid = valid;

        return {"property": [ property ]};
    }

    static setCabinetDeviceInfo(data){
        if(this.colonyGatesValue[data.gateId]){
            this.colonyGatesValue[data.gateId].onlineStatus = data.property.onlineStatus;
            this.colonyGatesValue[data.gateId].valid = data.property.valid;
            this.colonyGatesValue[data.gateId].loop = Object.assign({}, data.property.loop);
            DeviceEventEmitter.emit("colonyCabinet");
            this.updateColonyGateValueCache();
        } else {
            XLog.e("setCabinetDeviceInfo: gateId not found ", data.gateId);
        }     
    }

    static getLocalCabinetDeviceInfo(){
        return {"property": this.colonyGatesValue[this.gateId]};
    }

    static setColonyCabinetDeviceLight(gateId, loops, value, bClearStrategy = true){
        if(bClearStrategy) {
            let cabinet = this.colonyGatesMap[gateId];
            if(cabinet) {
                for (var loop of loops){
                    let item = cabinet.loop[loop];
                    if (item){
                        item.strategyId = 0;
                    }
                }
            }
        }
        this.updateGateCurrentValue(gateId, "loop", {loops, value});
        this.updateColonyGateValueCache();
    }

    static setColonyCabinetDeviceStrategyId(gateId, loops, strategyId){
        let dirty = false;
        let cabinet = this.colonyGatesMap[gateId];
        if(cabinet) {
            for (var loop of loops){
                let item = cabinet.loop[loop];
                if (item){
                    item.strategyId = strategyId;
                    dirty = true;
                }
            }
            if(dirty) {
                this.updateColonyGateCache();
            }
        } else {
            XLog.e("setColonyCabinetDeviceStrategyId error", gateId);
        }
    }

    static setSegmentCabinetDeviceLight(sectionId, value){
        let section = this.tunnelGatesMap[sectionId];
        if(section) {
            section.brightness = value;
            section.strategyId = 0;
            DeviceEventEmitter.emit("tunnelCabinet");
            this.updateTunnelGateCache();
        }
    }

    static setSegmentCabinetDeviceStrategyId(sectionId, strategyId){
        let section = this.tunnelGatesMap[sectionId];
        if(section) {
            section.strategyId = strategyId;
            DeviceEventEmitter.emit("tunnelCabinet");
            this.updateTunnelGateCache();
        }
    }

    static setSegmentCabinetDeviceLightByGateId(gateId, loops, value) {
        let dirty = false;
        for(let loop of loops||[]) {
            let section = this.tunnelGatesMap[this.gateSegmentMap[gateId]?.[loop]?.sectionId];
            if(section && value != section.brightness) {
                section.brightness = 0;
                section.strategyId = 0;
                dirty = true;
            }
        }
        if(dirty) {
            this.updateTunnelGateCache();
        }
    }

    static setSegmentCabinetDeviceStrategyByGateId(gateId, loops, strategyId) {
        let dirty = false;
        for(let loop of loops||[]) {
            let section = this.tunnelGatesMap[this.gateSegmentMap[gateId]?.[loop]?.sectionId];
            if(section && strategyId != section.strategyId) {
                section.brightness = 0;
                section.strategyId = 0;
                dirty = true;
            }
        }
        if(dirty) {
            this.updateTunnelGateCache();
        }
    }

    static updateServerIP(gateId, serverIp, serverId){
        if ((gateId != this.gateId) || (serverIp == this.serverIp)){
            return true;
        }
        this.serverId = serverId;
        this.serverIp = serverIp;
        if(this.Cache_Enable){
            RNStorage.serverInfo = {
                serverIp: this.serverIp,
                serverId: this.serverId,
                serverKey: this.serverKey,
            };
        }
        return true;
    }

    static updateMaster(newMasterId, newMasterIp, newMasterSecret) {
        this.masterId = newMasterId;
        this.masterIp = newMasterIp;
        this.isMaster = (newMasterId == this.gateId);
        this.masterSecret = newMasterSecret;
        if(this.Cache_Enable) {
            RNStorage.masterInfo = {
                masterIp: this.masterIp,
                masterId: this.masterId,
                isMaster: this.isMaster,
                masterSecret: this.masterSecret,
            };
        }
    }

    static queryStrategyById(strategyId) {
        return this.strategyListMap[strategyId];
    }

    static queryLoopsInSection(sectionId) {
        let localLoops = [];
        let colonyGatesMap = {};
        let section = this.tunnelGatesMap[sectionId];
        if(section) {
            for(let groupItem of section.group) {
                for(let loop of groupItem.loop||[]) {
                    if(loop.gateId == DataCenter.gateId) {
                        localLoops.push(loop.loopNumber);
                    } else {
                        let colonyGate = colonyGatesMap[loop.gateId]|| [];
                        colonyGate.push(loop.loopNumber);
                        colonyGatesMap[loop.gateId] = colonyGate;
                    }
                }
                
            }
            return {local: localLoops, colony: colonyGatesMap};
        } else {
            return {local:[], colony:{}};
        }
    }

    static queryGateLoopsBrightness(gateId, loops) {
        let ret = [];
        for(let loopNumber of loops||[]) {
            let gate = this.colonyGatesMap[gateId];
            if(gate) {
                ret.push({gateName:gate.gateName, loopName: gate.loop[loopNumber]?.loopName, 
                    loopNumber:loopNumber, 
                    loopCurrentValue: this.queryGateLoopCurrentValue(gateId, loopNumber)});
            }
        }
        return ret;
    }

    static queryGateLoopCurrentValue(gateId, loopNumber) {
        let gate = this.colonyGatesValue[gateId];
        if(gate) {
            let loopItem = gate.loop?.[loopNumber];
            if(loopItem) {
                return loopItem.loopCurrentValue;
            }
        }
        return 0;
    }

    static updateGateCurrentValue(gateId, key, obj) {
        let gateValue = this.colonyGatesValue[gateId];
        if(gateValue) {
            if(key == "loop") {
                for (var loopNumber of obj.loops){
                    let loopValue = gateValue.loop[loopNumber] || {};
                    loopValue.loopCurrentValue = obj.value;
                    gateValue.loop[loopNumber] = loopValue;
                }
                this.colonyGatesValue[gateId] = gateValue;
                return true;
            } else if(key == "onlineStatus") {
                gateValue.onlineStatus = obj;
                this.colonyGatesValue[gateId] = gateValue;
                return true;
            }
            return false;
        } else {
            XLog.e("no gate value for update:",gateId, this.colonyGatesValue);
            return false;
        }
    }

    static getColonyOriginData() {
        return this.colonyOriginData;
    }

    static getTunnelOriginData() {
        return this.tunnelOriginData;
    }

    static getStrategyOriginData() {
        return this.strategyListOriginData;
    }

    static getGateValuesData() {
        return this.colonyGatesValue;
    }

    static setGateValuesData(data) {
        for(let key of Object.keys(data)) {
            if(key != "local" && key != this.gateId) {
                this.colonyGatesValue[key] = data[key];
            }
        }
        this.updateColonyGateValueCache();
    }

    static initLoopControllerList(loops){
        this.loopControllerList = [];
        for(var loop of loops){
            let dev = {id: loop.id, index: loop.controllerNumber, address: loop.address, type: RS_Device_Type.LOOP_4WAY, option: SerialConfig, interface: InterfaceType.USB_SERIAL};
            //dev.key = dev.type + "_" + dev.index;
            dev.key = ""+dev.type;
            dev.option.port = DevicePort.LOOPCONTROLLER_PORT;
            this.loopControllerList.push(dev);
        }
    }

    static initSmartMeterList(meters){
        this.smartMeterList = [];
        for(var meter of meters){
            let dev = {id: meter.id, index: meter.meterNumber, address: meter.address, type: RS_Device_Type.METER, option: MeterConfig, interface: InterfaceType.USB_SERIAL};
            //dev.key = dev.type + "_" + dev.index;
            dev.key = ""+dev.type;
            dev.option.port = DevicePort.SMART_PORT;
            this.smartMeterList.push(dev);
        }
    }

    static updateSmartMeterData(parserData){
        if(Object.keys(parserData.realtime).length > 0){
            this.smartMeterData.realtime = parserData.realtime;
        }
        if(Object.keys(parserData.stat).length > 0){
            this.smartMeterData.stat = parserData.stat;
        }
    }
}